<template>
  <div class="content">
    <div>arrow demo</div>
    <div class="left" ref="left">
      left
    </div>
    <div class="right" ref="right">
      right
    </div>
    <canvas width="800" height="600" ref="canvas"></canvas>
  </div>
</template>

<script>
export default {
  mounted() {
    const res = this.getSTPostion()
    const dist = this.distant(res.source, res.dest)
    const angle = this.angle(res.source, res.dest)

    console.log(res, dist, angle)
    this.drawArrow(this.getCanvasCtx(), 0, 0, 100, 100)
    this.drawArrow(this.getCanvasCtx(), 100, 100, 100, 400)
    this.drawArrow(this.getCanvasCtx(), 0, 0, 300, 100)
  },
  methods: {
    getSTPostion() {
      const left = this.$refs['left'].getBoundingClientRect()
      const right = this.$refs['right'].getBoundingClientRect()
      const canvas = this.$refs['canvas'].getBoundingClientRect()
      debugger
      return {
        source: {
          x: left.x - canvas.x - left.width / 2,
          y: left.y + left.height - canvas.y
        },
        dest: {
          x: right.x - canvas.x,
          y: right.y - right.height / 2 - canvas.y
        }
      }
    },
    angle(from, to) {
      return (Math.atan2(to.y - from.y, to.x - from.x) * 180) / Math.PI //弧度转角度
    },
    distant(a, b) {
      let dx = Number(a.x) - Number(b.x)
      let dy = Number(a.y) - Number(b.y)
      return Math.pow(dx * dx + dy * dy, 0.5)
    },
    getCanvasCtx() {
      return this.$refs['canvas'].getContext('2d')
    },
    // eslint-disable-next-line prettier/prettier
    /**
      ctx：Canvas绘图环境
      fromX, fromY：起点坐标（也可以换成p1，只不过它是一个数组）
      toX, toY：终点坐标 (也可以换成p2，只不过它是一个数组)
      theta：三角箭头与斜边的夹角
      headlen：三角箭头斜边长度
      width：箭头线宽度
      color：箭头颜色
     */
    drawArrow(ctx, fromX, fromY, toX, toY, theta = 30, headlen = 10, width = 1, color = '#000') {
      // 计算各角度和对应的P2,P3坐标
      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI
      let angle1 = ((angle + theta) * Math.PI) / 180
      let angle2 = ((angle - theta) * Math.PI) / 180
      let topX = headlen * Math.cos(angle1)
      let topY = headlen * Math.sin(angle1)
      let botX = headlen * Math.cos(angle2)
      let botY = headlen * Math.sin(angle2)

      ctx.save()
      ctx.beginPath()

      let arrowX = fromX - topX
      let arrowY = fromY - topY

      ctx.moveTo(arrowX, arrowY)
      ctx.moveTo(fromX, fromY)
      ctx.lineTo(toX, toY)
      arrowX = toX + topX
      arrowY = toY + topY
      ctx.moveTo(arrowX, arrowY)
      ctx.lineTo(toX, toY)
      arrowX = toX + botX
      arrowY = toY + botY
      ctx.lineTo(arrowX, arrowY)
      ctx.strokeStyle = color
      ctx.lineWidth = width
      ctx.stroke()
      ctx.restore()
    }
  }
}
</script>

<style lang="less" scoped>
.content {
  position: relative;
  height: 900px;
  canvas {
    position: absolute;
    left: 0;
    top: 0;
  }
  .left {
    position: absolute;
    left: 300px;
    top: 10x;
    width: 100px;
    height: 100px;
    border: 1px solid #0071ff;
  }
  .right {
    position: absolute;
    left: 200px;
    top: 240px;
    width: 40px;
    height: 40px;
    border: 1px solid #0071ff;
  }
}
</style>
